package com.lianda.mutiple.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

//异步批量查询
public class BatchQueryMain {

    static LinkedBlockingQueue<Request> queue = new LinkedBlockingQueue<>();


    //初始化
    public static void init() {
        ScheduledExecutorService scheduledExecutorService = Executors
                .newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    //1.取出请求
                    int size = queue.size();
                    if (size == 0) {
                        return;
                    }

                    List<Request> requests = new ArrayList<>();
                    for (int i = 0; i < size; i++) {
                        Request poll = queue.poll();
                        requests.add(poll);
                    }

                    //2.组装一个批量查询请求参数
                    List<String> movieCodes = new ArrayList<>();
                    for (Request request : requests) {
                        movieCodes.add(request.getMovieCode());
                    }

                    //3.请求
                    System.out.println("本次合并请求数量：" + movieCodes.size());
                    //一个合并请求
                    List<Map<String, Object>> responses = new ArrayList<>();

                    //4.list转map便于查找，批量请求，得到结果list
                    Map<String, Map<String, Object>> responseMap = new HashMap<>();
                    for (Map<String, Object> resp : responses) {
                        String code = resp.get("code").toString();
                        responseMap.put(code, resp);
                    }

                    //5.将结果响应给每一个单独用户的请求
                    for (Request request : requests) {
                        Map<String, Object> result = responseMap.get(request.getMovieCode());

                        //将结果返回给对应的请求线程
                        //2个线程通信，异步编程赋值
                        request.getFuture().complete(result);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 0, 10, TimeUnit.MILLISECONDS);
    }

    //并发查询电影信息
    public Map<String, Object> queryMovie(String movieCode) throws Exception {
        Request request = new Request();
        request.setMovieCode(movieCode);

        CompletableFuture<Map<String, Object>> future = new CompletableFuture<>();
        request.setFuture(future);

        //定时任务去处理请求
        queue.add(request);

        //阻塞等待结果
        Map<String, Object> stringObjectMap = future.get();
        return stringObjectMap;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Request {

        private String movieCode;

        private CompletableFuture<Map<String, Object>> future;

    }
}




